#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
HDF5文件结构读取器
读取HDF5文件并显示其内部结构
"""

import h5py
import numpy as np
import os
import sys

def print_hdf5_structure(name, obj, indent=0):
    """递归打印HDF5文件结构"""
    spaces = "  " * indent
    
    if isinstance(obj, h5py.Group):
        print(f"{spaces}📁 组 (Group): {name}")
        print(f"{spaces}   - 子项数量: {len(obj)}")
        if obj.attrs:
            print(f"{spaces}   - 属性:")
            for attr_name, attr_value in obj.attrs.items():
                print(f"{spaces}     • {attr_name}: {attr_value}")
        
        # 递归遍历子项
        for key in obj.keys():
            print_hdf5_structure(key, obj[key], indent + 1)
    
    elif isinstance(obj, h5py.Dataset):
        print(f"{spaces}📄 数据集 (Dataset): {name}")
        print(f"{spaces}   - 形状: {obj.shape}")
        print(f"{spaces}   - 数据类型: {obj.dtype}")
        print(f"{spaces}   - 大小: {obj.size} 个元素")
        
        # 计算数据大小（MB）
        size_mb = obj.nbytes / (1024 * 1024)
        print(f"{spaces}   - 占用空间: {size_mb:.2f} MB")
        
        # 显示属性
        if obj.attrs:
            print(f"{spaces}   - 属性:")
            for attr_name, attr_value in obj.attrs.items():
                print(f"{spaces}     • {attr_name}: {attr_value}")
        
        # 显示数据预览（如果数据不是太大）
        if obj.size > 0 and obj.size <= 100:
            print(f"{spaces}   - 数据预览:")
            try:
                data = obj[:]
                if data.ndim == 1:
                    print(f"{spaces}     {data[:10]}{'...' if len(data) > 10 else ''}")
                else:
                    print(f"{spaces}     形状: {data.shape}")
                    print(f"{spaces}     前几个值: {data.flat[:5]}")
            except Exception as e:
                print(f"{spaces}     无法读取数据: {e}")
        elif obj.size > 100:
            print(f"{spaces}   - 数据太大，显示前5个值:")
            try:
                data_sample = obj.flat[:5]
                print(f"{spaces}     {data_sample}")
            except Exception as e:
                # 对于多维数组，使用替代方法
                try:
                    data_sample = obj[:1].flat[:5]
                    print(f"{spaces}     {data_sample}")
                except Exception as e2:
                    print(f"{spaces}     无法读取数据: {e2}")

def read_hdf5_file(filepath):
    """读取HDF5文件并显示结构"""
    
    if not os.path.exists(filepath):
        print(f"❌ 错误：文件 {filepath} 不存在")
        return
    
    try:
        print(f"🔍 正在读取HDF5文件: {filepath}")
        print(f"📏 文件大小: {os.path.getsize(filepath) / (1024*1024):.2f} MB")
        print("=" * 60)
        
        with h5py.File(filepath, 'r') as f:
            print(f"📋 文件信息:")
            print(f"   - HDF5版本: {f.libver}")
            print(f"   - 根组键数: {len(f.keys())}")
            
            # 显示根级别属性
            if f.attrs:
                print(f"   - 根属性:")
                for attr_name, attr_value in f.attrs.items():
                    print(f"     • {attr_name}: {attr_value}")
            
            print("\n🌳 文件结构:")
            print("-" * 40)
            
            # 如果根目录为空
            if len(f.keys()) == 0:
                print("   (空文件)")
            else:
                # 遍历根目录下的所有项
                for key in f.keys():
                    print_hdf5_structure(key, f[key])
            
    except Exception as e:
        print(f"❌ 读取文件时发生错误: {e}")
        print(f"   请确保文件是有效的HDF5格式")

def main():
    """主函数"""
    print("🚀 HDF5文件结构读取器")
    print("=" * 60)
    
    # 默认文件路径
    default_file = "DAQ_h5/CM01_01_data_20250611_09_18_57.h5"
    
    # 检查命令行参数
    if len(sys.argv) > 1:
        filepath = sys.argv[1]
    else:
        filepath = default_file
    
    print(f"📂 目标文件: {filepath}")
    
    # 读取HDF5文件
    read_hdf5_file(filepath)
    
    print("\n" + "=" * 60)
    print("✅ 完成!")

if __name__ == "__main__":
    main() 